#!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*-
##--------------------------------------------------------------------------##
##
## Copyright (C) 1998-2003 Markus Oberhumer <markus@oberhumer.com>
## Copyright (C) 2003 Mt. Hood Playing Card Co.
## Copyright (C) 2005-2010 Skomoroh <skomoroh@users.sourceforge.net>
## Copyright (C) 2010-2013 Jeremy Austin-Bardo <tjaustinbardo@gmail.com>
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, version 3 of the License.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program.  If not, see <http://www.gnu.org/licenses/>.
##
##--------------------------------------------------------------------------##
"""
"""
__docformat__ = "restructuredtext en"

from datetime import datetime, timedelta


def format_time(time):
    """
    Format a date/time value

    .. format_time(time:int|datetime|timedelta) -> str
    """
    if isinstance(time, (datetime,)):
        return '{:%Y-%m-%d %h:%M}'.format(d)
    if isinstance(time, (timedelta,)):
        time = int(time.total_seconds())
    assert isinstance(time, (int,))
    time = (time / 3600, (time % 3600) / 60, time % 60)
    return ('{1:02}:{2:02}' if time[0] == 0
                          else '{0:02}:{1:02}:{2:02}').format(*time)


kwdefault = lambda k, **d: (k.update(dict((f, v,) for f, v in d.items()
                                                  if f not in k)))


class Timer(object):

    _complete = True

    def __init__(self):
        """
        Init timer
        """
        self.__timer = {}

    def __call__(self, restart):
        """
        Reset timer.
        """
        self._complete = False
        self.__timer.update({'update': datetime.today(), 'elapsed': timedelta(),
                             'paused': 0.0})
        if not restart:
            self.__timer.update({'start': datetime.today(),
                                 'total': timedelta()})

    def adjust(self):
        """
        Adjust current time.
        """
        self.__timer['update'] = datetime.today()

    def update(self):
        """
        Update timer values.
        """
        if self._complete:
            return
        timer = self.__timer
        delta = datetime.today() - timer['update']
        if delta:
            timer['elapsed'] += delta
            timer['total'] += delta
        timer['update'] = datetime.today()

    @property
    def elapsed(self):
        return self.__timer['elapsed']

    @property
    def started(self):
        return self.__timer['start']

    def __str__(self):
        """
        Return current timer value.
        """
        self.update()
        return format_time(self.__timer['elapsed'])


def openURL(url):
    import webbrowser
    try:
        webbrowser.open(url)
    except OSError:                  # raised on windows if link is unreadable
        pass
    except:
        return False
    return True



from collections import namedtuple

ImagePair = namedtuple('CardImagePair', ('back', 'face'))
BACK = namedtuple('CardBack', ('name', 'image'))
OFFSET = namedtuple('CardOffset', ('xoffset', 'yoffset'))
SPACE = namedtuple('CardSpace', ('xspace', 'yspace'))
BASE = namedtuple('CardBase', ('negative', 'positive'))


scale_ = lambda v, f: int(round(v * f))


class Scale(namedtuple('Size', 'x y')):
    @property
    def xscale(self):
        return self.x
    @property
    def yscale(self):
        return self.y


class Size(namedtuple('Size', 'w h')):
    def _add_size(self, size):
        assert isinstance(size, (Size,))
        return self._replace(w=self.w + size.w, h=self.h + size.h)
    @property
    def width(self):
        return self.w
    @property
    def height(self):
        return self.h
    def _scale(self, scale):
        assert isinstance(scale, (Scale,))
        return self._replace(w=scale_(self.w, scale.xscale),
                             h=scale_(self.h, scale.yscale))


class Margin(namedtuple('Margin', 'x y')):
    def _add_size(self, size):
        assert isinstance(size, (Size,))
        return self._replace(x=self.x + size.w, y=self.y + size.h)
    @property
    def xmargin(self):
        return self.x
    @property
    def ymargin(self):
        return self.y


class Point(namedtuple('Point', 'x y')):
    def _move(self, point):
        assert isinstance(point, (Point,))
        return self._replace(x=self.x + point.x, y=self.y + point.y)
    def _scale(self, scale):
        assert isinstance(scale, (Scale,))
        return self._replace(x=scale_(self.x, scale.xscale),
                             y=scale_(self.y, scale.yscale))


class Offset(namedtuple('Offset', 'x y')):
    def _add_size(self, size):
        assert isinstance(size, (Size,))
        return self._replace(x=self.x + size.w, y=self.y + size.h)
    @property
    def xoffset(self):
        return self.x
    @property
    def yoffset(self):
        return self.y


class Delta(namedtuple('Delta', 'x y')):
    def _add_size(self, size):
        assert isinstance(size, (Size,))
        return self._replace(x=self.x + size.w, y=self.y + size.h)
    @property
    def xdelta(self):
        return self.x
    @property
    def ydelta(self):
        return self.y


class Block(namedtuple('Block', 'l t r b')):
    @staticmethod
    def _from_points(spoint, epoint):
        assert isinstance(spoint, (Point,)) and isinstance(epoint, (Point,))
        return Block(l=spoint.x, t=spoint.y, r=epoint.x, b=epoint.y)
    @staticmethod
    def _from_point_size(point, size):
        assert isinstance(point, (Point,)) and isinstance(size, (Size,))
        return Block(l=point.x, t=point.y,
                     r=point.x + size.w, b=point.y + size.h)
    def _scale(self, scale):
        assert isinstance(scale, (Scale,))
        return self._replace(l=scale_(self.l, scale.xscale),
                             t=scale_(self.t, scale.yscale),
                             r=scale_(self.r, scale.xscale),
                             b=scale_(self.b, scale.yscale))


class Cast(namedtuple('CardCast', 'deck suit rank color force')):
    def __new__(cls, deck, suit, rank, color=0, force=0):
        return super(Cast, cls).__new__(cls, deck, suit, rank, color, force)